﻿using System.Collections.Generic;

namespace System.Linq
{
    /// <summary>
    /// Enumerable 클래스 확장입니다.
    /// </summary>
    public static class ExtendEnumerable
    {
        #region Extend Method

        /// <summary>
        /// 지정된 시퀀스들을 연결합니다.
        /// </summary>
        /// <typeparam name="TSource">입력 시퀀스 요소의 형식입니다.</typeparam>
        /// <param name="target">호출한 대상 시퀀스입니다.</param>
        /// <param name="arrays">연결할 시퀀스 배열입니다.</param>
        /// <returns>지정된 시퀀스들이 연결된 요소가 들어 있는 시퀀스입니다.</returns>
        public static IEnumerable<TSource> Concat<TSource>(this IEnumerable<TSource> target, params IEnumerable<TSource>[] arrays)
        {
            if(arrays != null)
            {
                foreach(IEnumerable<TSource> array in arrays)
                {
                    target = target.Concat(array).ToArray();
                }
            }
            return target;
        }

        /// <summary>
        /// System.Collections.Generic.IEnumerable 내에 포함된 default 값을 제거합니다.
        /// </summary>
        /// <typeparam name="T">데이터 형식입니다.</typeparam>
        /// <param name="target">호출한 대상 인스턴스입니다.</param>
        /// <returns>default 값이 제외된 System.Collections.Generic.IEnumerable 입니다.</returns>
        public static IEnumerable<T> Trim<T>(this IEnumerable<T> target) where T : struct
        {
            return target.Where(item => !EqualityComparer<T>.Default.Equals(item, default(T)));
        }

        /// <summary>
        /// System.Collections.Generic.IEnumerable 내의 값을 치환합니다.
        /// </summary>
        /// <typeparam name="T">데이터 형식입니다.</typeparam>
        /// <param name="target">호출한 대상 인스턴스입니다.</param>
        /// <param name="oldValue">변경될 값입니다.</param>
        /// <param name="newValue">변경할 값입니다.</param>
        /// <returns>치환된 System.Collections.Generic.IEnumerable 입니다.</returns>
        public static IEnumerable<T> Replace<T>(this IEnumerable<T> target, T oldValue, T newValue) where T : struct
        {
            T[] result = new T[target.Count()];
            for(int index = 0; index < target.Count(); index++)
            {
                result[index] = EqualityComparer<T>.Default.Equals(target.ElementAt(index), oldValue) ? newValue : target.ElementAt(index);
            }
            return result;
        }

        #endregion Extend Method
    }
}